#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

// stdio重定向
static int out_fd = -1;
static int err_fd = -1;
static const char *log_info_file = "/root/info.log";
static const char *log_error_file = "/root/error.log";
static const char *daemon_pid_file = "/run/daemon-test.pid";

extern int daemon_forever(void);
static void signal_handler(int sig);

static struct sigaction sig_actions = {
    .sa_handler = signal_handler,
    .sa_flags = 0
};

// 信号处理函数
void signal_handler(int sig) {
    if (sig != SIGTERM && sig != SIGKILL) {
        return;
    }
    // 这里可以添加接收到SIGTERM信号后的具体处理逻辑，例如释放资源等
    fprintf(stdout, "Received SIGTERM signal, cleaning up and exiting...\n");
    // 关闭标准输出文件句柄
    if (out_fd!= -1) {
        close(out_fd);
    }
    // 关闭标准错误输出文件句柄
    if (err_fd!= -1) {
        close(err_fd);
    }
    // 示例中简单退出，实际可根据需求完善清理逻辑
    exit(0);
    return;
}

static inline int daemon_init_signal(void)
{
    sigemptyset(&sig_actions.sa_mask);
    if (sigaction(SIGTERM, &sig_actions, NULL) == -1) {
        perror("sigaction error");
        return -1;
    }
    return 0;
}

static int daemon_init_stdio(void)
{
    // 重定向标准输出到 log_info_file
    out_fd = open(log_info_file, O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (out_fd == -1) {
        perror("open info.log error");
        return -1;
    }
    if (dup2(out_fd, STDOUT_FILENO) == -1) {
        perror("dup2 error");
        close(out_fd);
        return -1;
    }
    // 设置标准输出为行缓冲模式
    setvbuf(stdout, NULL, _IOLBF, 0);
    
    // 重定向标准错误输出到 log_error_file
    err_fd = open(log_error_file, O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (err_fd == -1) {
        perror("open error.log error");
        close(out_fd);
        return -1;
    }
    if (dup2(err_fd, STDERR_FILENO) == -1) {
        perror("dup2 error");
        close(out_fd);
        close(err_fd);
        return -1;
    }
    setvbuf(stderr, NULL, _IOLBF, 0);
    return 0;
}

// 注册信号处理函数
static int daemon_init(void)
{
    int ret = 0;
    ret = daemon_init_signal();
    if (ret != 0) {
        return ret;
    }
    ret = daemon_init_stdio();
    if (ret != 0) {
        return ret;
    }
    return 0;
}

static int daemon_save_pid(void)
{
    FILE *pid_file_fd = NULL;
    pid_t pid = getpid();
    // 打开文件用于写入PID
    pid_file_fd = fopen(daemon_pid_file, "w");
    if (pid_file_fd == NULL) {
        perror("open daemon-test.pid");
        return -1;
    }
    // 将PID写入文件
    fprintf(pid_file_fd, "%d", pid);
    fclose(pid_file_fd);
    return 0;
}

static void daemon_main(void)
{
    /**
    pid_t sid = -1;
    // 子进程成为新会话组长，脱离终端
    sid = setsid();
    if (sid < 0) {
        perror("setsid error");
        return;
    }
    */
    if (daemon_save_pid() != 0) {
        return;
    }
    if (daemon_init() != 0) {
        return;
    }
    daemon_forever();
}

int main() {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork error");
        return -1;
    } else if (pid == 0) {
        daemon_main();
        return 0;
    } else {
        return 0;
    }
    return 0;
}
